package demo1;

public class String_note {
    public static void main(String[] args) {
        //使用：
        String str1 = "hello"; //这是一种简化的写法
        String str2 = new String("hello"); //本质是这样的

        //String是一种引用数据类型，内部并不存储字符串本身
        //String存的是字符数组和一个hash值


        System.out.println("==========================");
        System.out.println(str1.length()); //这是一个方法
        int[] arr1 = {1, 2, 3, 4, 5};
        System.out.println(arr1.length); //length后面没有(),说明它不是一个方法


        System.out.println("==========================");
        System.out.println("空字符串的讨论");
        System.out.println(str1.isEmpty()); //判断字符串是否为空
        String str3 = null; //这表示str4不指向任何对象
        String str4 = ""; //这表示一个空字符串，两者不一样
        System.out.println(str4.isEmpty()); //这样的结果是true，它是一个空字符串
        //System.out.println(str3.isEmpty()); //这样会空指针报错
        System.out.println("hello".length());


        System.out.println("==========================");
        System.out.println("比较字符串是否相等");
        String str5 = new String("hello");
        System.out.println(str2 == str5); //这样比较的是str2和str5的地址,因为它们都是直接new出来的，都有自己单独的地址，所以结果为false
        System.out.println(str1.equals(str2)); //这才比较的是字符数组，因为String类重写了toString方法
        String str6 = "hello";
        System.out.println(str1 == str6); //会发现结果是true
        //字符串常量池存放的是由""引起来的字符串，存的是字符串常量值
        //如果要存的字符串在常量池没有，则存一个新的。若有，则获取这个字符串在常量池中的地址
        //在比较两个引用所指向的对象的内容是否一样，需要重写.equals方法
        //所以在比较自定义数据类型时，要重写hashcode和.equals方法


        System.out.println("==========================");
        System.out.println("比较字符串的大小");
        String str7 = "abcd";
        String str8 = "abcdef";
        String str9 = "Abcd";
        System.out.println(str7.compareTo(str8)); //String类实现了Comparable接口，重写了compareTo方法
        //比较的逻辑是跟C中的strcmp()一样的
        //忽略大小写比较？：
        System.out.println(str7.compareToIgnoreCase(str9));

        //比较两个字符串：
        //1. ==
        //2. .equals()
        //3. compareTo()
        //4. compareToIgnoreCase


        System.out.println("==========================");
        System.out.println("字符串的查找");
        //查找指定下标位置的字符：
        char ch1 = str7.charAt(1);
        System.out.println(ch1);
        //查找指定字符/字符串的位置：
        System.out.println(str7.indexOf('c'));
        System.out.println(str7.indexOf('c', 1)); //也可以从指定的下标位置开始查找
        System.out.println(str8.indexOf("ef"));
        //从右向左查找：
        System.out.println(str7.lastIndexOf('c'));


        System.out.println("==========================");
        System.out.println("字符串的转换");
        //其他数据类型与字符串之间的转换
        String str10 = String.valueOf(10);
        String str11 = String.valueOf('s');
        String str12 = String.valueOf("csgo");
        String str13 = String.valueOf(true);
        System.out.println(str10);
        System.out.println(str11);
        System.out.println(str12);
        System.out.println(str13);

        int data1 = Integer.parseInt("521");
        double data2 = Double.parseDouble("13.14");
        System.out.println(data1);
        System.out.println(data2);

        //大小写转换
        String str14 = str1.toUpperCase();
        System.out.println(str14);
        String str15 = "JOJO".toLowerCase();
        System.out.println(str15);
        //这里要注意的是，在Java中string是不可变的，大小写的转换，不是直接把str1从hello转化为HELLO，而是返回了一个新对象

        //字符串转字符数组
        char[] arr2 = str1.toCharArray();
        for(int i = 0; i < arr2.length; i++) {
            System.out.print(arr2[i] + " ");
        }
        System.out.println();


        System.out.println("==========================");
        System.out.println("格式化");
        String s1 = String.format("%.1f", data2);
        String s2 = String.format("%d-%d-%d", 2025, 4, 25);
        System.out.println(s1);
        System.out.println(s2);


        System.out.println("==========================");
        System.out.println("字符串替换");
        String str16 = "abcabdabfabg";
        String ret1 = str16.replace("ab","x"); //把所有"ab"替换为"x",这里返回的是一个新字符串，没有修改原字符串
        System.out.println(ret1);
        String ret2 = str16.replace('a','x'); //同上
        System.out.println(ret2);
        String ret3 = str16.replaceFirst("ab","z"); //只替换第一个
        String ret4 = str16.replaceAll("ab","z"); //替换所有
        System.out.println(ret3);
        System.out.println(ret4);


        System.out.println("==========================");
        System.out.println("字符串拆分");
        String str17 = "name=zhangsan&age=18";
        String[] ret5 = str17.split("&");
        //参数是以什么为分隔符，返回值时字符数组
        for (int i = 0; i < ret5.length; i++) {
            System.out.println(ret5[i]);
        }
        String str18 = "hello nice to meet you";
        String[] ret6 = str18.split(" ");
        for (int i = 0; i < ret6.length; i++) {
            System.out.println(ret6[i]);
        }
        String[] ret7 = str18.split(" ", 2); //指定分成的组数
        for (int i = 0; i < ret7.length; i++) {
            System.out.println(ret7[i]);
        }
        System.out.println("特殊情况！：");
        //若以 . | * + 作为分隔符，前面需要加上 \\ 来转义
        //若分隔符为\，则需要写\\\\
        String str19 = "202.203.208.5";
        String[] ret8 = str19.split("\\.");
        for (int i = 0; i < ret8.length; i++) {
            System.out.println(ret8[i]);
        }
        String str20 = "2006\\09\\17"; //一个\会让后面的数字转移，两个\\表示一个普通的\。
        String[] ret9 = str20.split("\\\\"); //因此这里需要\\来把\\作为分隔符。
        for (int i = 0; i < ret9.length; i++) {
            System.out.println(ret9[i]);
        }

        //多个分隔符用|连接
        String[] ret10 = str17.split("& | =");
        for (int i = 0; i < ret10.length; i++) {
            System.out.println(ret10[i]);
        }


        System.out.println("==========================");
        System.out.println("字符串的拆分");
        String str21 = "simple";
        String str22 = str21.substring(2); //参数是下标位置
        //若下标是0，则返回原字符串。若非零，则返回一个新字符串
        System.out.println(str22);
        String str23 = str21.substring(2, 4); //java中是左闭右开的
        System.out.println(str23);


        System.out.println("==========================");
        System.out.println("去除字符串左右两边的空格");
        String str24 = "   abc   def   ";
        String str25 = str24.trim();
        System.out.println(str25);


        System.out.println("==========================");
        System.out.println("String类是不可变对象，StringBuilder和StringBuffer类是可变对象");
        System.out.println("StringBuilder类");
        StringBuilder stringBuilder = new StringBuilder("abcd");
        stringBuilder.append(9);
        stringBuilder.append("efgh");
        stringBuilder.append("px").append(12.5);
        //这里返回的是原字符串，如果用string操作的话是返回一个新字符串
        System.out.println(stringBuilder);

        stringBuilder.setCharAt(0, 'k');
        System.out.println(stringBuilder);

        stringBuilder.insert(1,"ooooooooooooo");
        System.out.println(stringBuilder);

        stringBuilder.reverse();
        System.out.println(stringBuilder);

        //将StringBuilder类对象转化为String对象
        //不能强转
        String str26 = stringBuilder.toString();
        System.out.println(str26);
        //String转化为StringBuilder可以通过StringBuilder的类方法直接转，
        //但StringBuilder转String需要toString方法。

        System.out.println("StringBuffer类");
        //与StringBuilder类方法是基本一样的
        //StringBuffer类是一般使用在多线程下
    }
}
